#pragma once

#if defined(_WIN32) || defined(__WIN32__)

# include <io.h>

// Windows
#   define SYSTEM_WINDOWS
#   ifndef WIN32_LEAN_AND_MEAN
#       define WIN32_LEAN_AND_MEAN
#   endif
# ifndef NOMINMAX
#   define NOMINMAX
# endif
# include <winsock2.h>
# include <windows.h>

#else

# include <unistd.h>

#endif

#ifdef _MSC_VER

# if _MSC_VER < 1800
#   error This operating system is not supported by this library
# endif

# pragma warning(disable : 4251)
# pragma warning(disable : 4503)
# pragma warning(disable : 4996)
# define attr_packed()
# define force_inline
# define thr_local __declspec(thread)

#else

# define attr_packed() __attribute__((packed))

# if defined(__MINGW32__)
#   define force_inline inline
# else
#   define force_inline inline __attribute__((always_inline))
# endif
# define thr_local __thread

#endif

#include <stdint.h>
#include <climits>
#include <cstdio>
#include <cstdlib>
#undef __STRICT_ANSI__
#include <cstring>
#define __STRICT_ANSI__
#include <cassert>
#include <iostream>
#include <vector>
#include <map>
#include <set>
#include <bitset>
#include <unordered_map>
#include <unordered_set>
#include <deque>
#include <queue>
#include <list>
#include <tuple>
#include <memory>
#include <string>
#include <thread>
#include <mutex>
#include <algorithm>
#include <functional>
#include <algorithm>
#include <numeric>
#include <array>
#include <random>
#include <ctime>
